package
{
	import flash.events.EventDispatcher;
	import baseitems.Base;
	import baseitems.Item;
	import baseitems.Layer;
	import baseitems.LabelTextField;
	import property.ItemType;
	import windows.ComponentsWindow;
	
	/**
	 * все умное будет тут
	 * @author yaempechenki@gmail.com
	 */
	public class Controller extends EventDispatcher
	{
		private static var _instance:Controller;
		private var idCounter:int = 1;
		private var _selectedObject:Base;
		private var items:Vector.<Base>;
		
		public function Controller()
		{
			items = new Vector.<Base>;
		}
		
		public static function get instance():Controller
		{
			if (!_instance)
			{
				_instance = new Controller();
			}
			return _instance;
		}
		
		public function addObject(type:String):Base {
			var item:Base;
			if (type == ItemType.LAYER) {
				item = new Layer(idCounter, type);
			} else if (type == ItemType.LABEL) {
				item = new LabelTextField(idCounter, type);
			} else {
				item = new Item(idCounter, type);
			}
			
			items.push(item);
			idCounter++;
			return item;
		}
		
		public function set selectedObject(obj:Base):void
		{
			unselectAll();
			_selectedObject = obj;
			if (obj) {
				_selectedObject.selected = true;
			}
		}
		
		public function get selectedObject():Base
		{
			return _selectedObject;
		}
		
		public function get haveSelected():Boolean
		{
			return (_selectedObject != null);
		}
		
		private function unselectAll():void
		{
			for each (var item:Base in items)
			{
				item.selected = false;
			}
		}
		
		/**
		 * Удалить элемент и всех его потомков (если есть)
		 */
		public function deleteObject(id:int):void
		{
			var item:Base = getItemById(id);
			// удаляем всех потомков
			var childrens:Vector.<Base> = getItemsByParentId(id);
			if (childrens.length > 0)
			{
				for (var i:int = 0; i < childrens.length; i++)
				{
					deleteOneObject(childrens[i].id);
				}
			}
			// сам элемент
			deleteOneObject(id);
			// снимаем select 
			unselectAll();
			_selectedObject = null;
			if (items.length > 0)
			{
				Controller.instance.selectedObject = items[items.length - 1];
			}
		}
		
		/**
		 * Просто удалить 1 элемент
		 */
		private function deleteOneObject(id:int):void
		{
			var index:int = -1;
			for (var i:int = 0; i < items.length; i++)
			{
				if (items[i].id == id)
				{
					index = i;
					break;
				}
			}
			if (index != -1)
			{
				items.splice(index, 1);
			}
		}
		
		/**
		 * Весь список
		 */
		public function getItems():Vector.<Base>
		{
			return items;
		}
		
		/**
		 * Получить элемент по id
		 */
		public function getItemById(id:int):Base
		{
			for each (var item:Base in items)
			{
				if (item.id == id)
				{
					return item;
				}
			}
			return null;
		}
		
		/**
		 * Список детей по id предка
		 */
		public function getItemsByParentId(parentId:int):Vector.<Base>
		{
			var result:Vector.<Base> = new Vector.<Base>;
			for each (var item:Base in items)
			{
				if (item.selfParent && item.selfParent.id == parentId)
				{
					result.push(item);
				}
			}
			return result;
		}
		
		/**
		 * Список уникальных парентов
		 */
		public function getParentList():Array
		{
			var result:Array = [];
			for each (var child:Base in items)
			{
				if (!child.selfParent)
					continue;
				if (result.indexOf(child.selfParent.id) != -1)
					continue;
				result.push(child.selfParent.id);
			}
			return result;
		}
		
		/**
		 * Вернет красивый массив левелов и айдишников [0][4,54,6,47]
		 */
		public function getLevelsList():Object {
			var category_array:Object = {};
			var items:Vector.<Base> = Controller.instance.getItems();
			for each (var item:Base in items) {
				var parent_id:int = 0;
				if (item.selfParent) parent_id = item.selfParent.id;
				if (!category_array[parent_id]) category_array[parent_id] = [];
				category_array[parent_id].push({ 'node_id':item.id, 'parent_id':parent_id, 'title':item.type });
			}
			
			var levelTree:Object = { };
			outTree(0, 0);
			function outTree(parent_id:int, level:int):void {
				if (category_array[parent_id]) { //Если категория с таким parent_id существует
					for each (var value:Object in category_array[parent_id]) { //Обходим
						// выводим
						if (!levelTree[level]) levelTree[level] = [];
						levelTree[level].push(value.node_id);
						level++; // Увеличиваем уровень вложености
						outTree(value.node_id, level);
						level--; // Уменьшаем уровень вложености
					}
				}
			}
			return levelTree;
		}
		
		public function clearAll():void 
		{
			unselectAll();
			items = new Vector.<Base>;
			_selectedObject = null;
		}
		
		public function duplicateItem():void 
		{
			var fromItem:Base = _selectedObject;
			var toItem:Base = addObject(fromItem.type);
			trace("> copy from", fromItem.id, "to", toItem.id);
			Controller.instance.selectedObject = toItem;
			toItem.width = fromItem.width;
			toItem.height = fromItem.height;
			toItem.anchor = fromItem.anchor;
			toItem.posAlign = fromItem.posAlign;
			toItem.selfParent = fromItem.selfParent;
			toItem.percentWidth = fromItem.percentWidth;
			toItem.percentHeight = fromItem.percentHeight;
			toItem.percentWidthEnabled = fromItem.percentWidthEnabled;
			toItem.percentHeightEnabled = fromItem.percentHeightEnabled;
			toItem.wstack = fromItem.wstack;
			toItem.hstack = fromItem.hstack;
			toItem.copySize = fromItem.copySize;
			toItem.stackAlign = fromItem.stackAlign;
			toItem.labelAlign = fromItem.labelAlign;
			toItem.textFieldSize = fromItem.textFieldSize;
			
			// бежим по всем ищем родителя fromItem.id
			// рекурсивно копируем всех нахер
			/*var childrens:Vector.<Base> = getItemsByParentId(fromItem.id);
			if (childrens.length > 0) {
				for each (var child:Base in childrens)
				{
					trace(" > copy child", child.id, "with parent.id =", child.selfParent.id );
					
					_selectedObject = child;
					_selectedObject.selfParent = toItem;
					duplicateItem();
				}
			}
			*/
			
		}
	}
}